package com.bruce.tool.push.jpush.core;

import cn.jiguang.common.ClientConfig;
import cn.jpush.api.JPushClient;
import cn.jpush.api.push.PushResult;
import cn.jpush.api.push.model.Platform;
import cn.jpush.api.push.model.PushPayload;
import cn.jpush.api.push.model.audience.Audience;
import cn.jpush.api.push.model.notification.AndroidNotification;
import cn.jpush.api.push.model.notification.IosNotification;
import cn.jpush.api.push.model.notification.Notification;
import com.bruce.tool.common.exception.ExceptionUtils;
import com.bruce.tool.common.util.LogUtils;
import com.bruce.tool.common.util.string.JsonUtils;
import com.bruce.tool.common.util.string.StringUtils;
import com.bruce.tool.common.util.valid.ValidUtils;
import com.bruce.tool.push.jpush.config.JPusherConfig;
import com.bruce.tool.push.jpush.constant.DeviceType;
import com.bruce.tool.push.jpush.constant.Target;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * 功能 :
 *
 * @author : Bruce(刘正航) 11:15 AM 2018/12/3
 */
@Slf4j
@Component
public abstract class JPusher {

    @Autowired
    protected JPusherConfig jPusherConfig;

    /**
     * 推送到ios
     **/
    public boolean push2ios(JMessage JMessage) {
        return execute(Target.REGISTRATION_ID, DeviceType.IOS, JMessage);
    }

    /**
     * 推送到android
     **/
    public boolean push2android(JMessage JMessage) {
        return execute(Target.REGISTRATION_ID, DeviceType.ANDROID, JMessage);
    }

    /**
     * 推送到所有类型终端设备
     **/
    public boolean push2device(JMessage JMessage) {
        return execute(Target.REGISTRATION_ID, DeviceType.ALL, JMessage);
    }

    /**
     * 推送到指定账户
     **/
    public boolean push2account(JMessage JMessage) {
        return execute(Target.REGISTRATION_ID, DeviceType.ALL, JMessage);
    }

    /**
     * 推送到指定账户
     **/
    public boolean push2alias(JMessage JMessage) {
        return execute(Target.ALIAS, DeviceType.ALL, JMessage);
    }

    /**
     * 推送给自定义标签
     **/
    public boolean push2tag(JMessage JMessage) {
        return execute(Target.TAG, DeviceType.ALL, JMessage);
    }

    /**
     * 推送给所有目标终端
     **/
    public boolean push2all(JMessage JMessage) {
        return execute(Target.ALL, DeviceType.ALL, JMessage);
    }

    /**
     * 执行消息推送
     **/
    public boolean execute(Target target, DeviceType deviceType, JMessage JMessage) {
        // 校验配置内容
        ValidUtils.valid(jPusherConfig);
        // 校验消息内容
        ValidUtils.valid(JMessage);

        return push(initRequest(target, deviceType, JMessage));
    }

    /**
     * 执行推送
     **/
    private boolean push(PushPayload pushRequest) {
        try {
            JPushClient client = new JPushClient(jPusherConfig.getAccessKeySecret(), jPusherConfig.getAccessKeyId(), null, ClientConfig.getInstance());
            PushResult pushResponse = client.sendPush(pushRequest);
            LogUtils.info(log, "消息推送,返回结果:{}", JsonUtils.objToStr(pushResponse));
            return true;
        } catch (Exception e) {
            ExceptionUtils.printStackTrace(e);
            return false;
        }
    }

    /**
     * 初始化请求对象
     **/
    private PushPayload initRequest(Target target, DeviceType deviceType, JMessage jMessage) {
        PushPayload.Builder builder = PushPayload.newBuilder();
        // 推送目标
        initTarget(jMessage, builder, target, deviceType);

        //
        notification(builder, deviceType, jMessage);

        return builder.build();
    }

    private void notification(PushPayload.Builder builder, DeviceType deviceType, JMessage jMessage) {
        Notification.Builder newBuilder = Notification.newBuilder();
        switch (deviceType) {
            case ANDROID:
                android(newBuilder, jMessage);
                break;
            case IOS:
                ios(newBuilder, jMessage);
                break;
            default:
                android(newBuilder, jMessage);
                ios(newBuilder, jMessage);
                break;
        }
        builder.setNotification(newBuilder.build());
    }

    private void ios(Notification.Builder builder, JMessage jMessage) {
        IosNotification iosNotification = IosNotification.newBuilder()
                .setAlert(jMessage.getMessage())
                .setBadge(+1)
                .setSound("happy")
                .build();
        builder.addPlatformNotification(iosNotification);
    }

    private void android(Notification.Builder builder, JMessage jMessage) {
        AndroidNotification androidNotification = AndroidNotification.newBuilder()
                .setAlert(jMessage.getMessage())
                .build();
        builder.addPlatformNotification(androidNotification);
    }

    /**
     * 推送目标配置
     **/
    private void initTarget(JMessage jMessage, PushPayload.Builder pushRequest, Target target, DeviceType deviceType) {
        /*设置推送目标*/
        // 设备类型 ANDROID iOS ALL
        transferDeviceType(pushRequest, deviceType);
        // 设置推送目标
        transferAudience(pushRequest, target, jMessage.getTargetValue());
    }

    private void transferAudience(PushPayload.Builder pushRequest, Target target, String targetValue) {
        List<String> targetValues = StringUtils.splitToList(targetValue);
        Audience audience;
        switch (target) {
            case TAG:
                audience = Audience.tag(targetValues);
                break;
            case TAG_AND:
                audience = Audience.tag_and(targetValues);
                break;
            case TAG_NOT:
                audience = Audience.tag_not(targetValues);
                break;
            case ALIAS:
                audience = Audience.alias(targetValues);
                break;
            case REGISTRATION_ID:
                audience = Audience.registrationId(targetValues);
                break;
            case SEGMENT:
                audience = Audience.segment(targetValues);
                break;
            case ABTEST:
                audience = Audience.abTest(targetValues);
                break;
            case ALL:
            default:
                audience = Audience.all();
                break;
        }
        pushRequest.setAudience(audience);
    }

    /**
     * 设置终端类型
     **/
    private void transferDeviceType(PushPayload.Builder pushRequest, DeviceType deviceType) {
        Platform platform;
        switch (deviceType) {
            case IOS:
                platform = Platform.ios();
                break;
            case ANDROID:
                platform = Platform.android();
                break;
            case ALL:
            default:
                platform = Platform.all();
                break;
        }
        pushRequest.setPlatform(platform);
    }

    /**
     * 子类负责获取其中一个
     **/
    public Long getAppKey(List<String> keys) {
        // TODO 如果有多个key,则需要继承此类,实现自己的推送方法
        return Long.valueOf(keys.get(0));
    }

}
